float4x4 g_mWorldViewProjection;
float4 g_vOverlayColor;
float g_fBlurSize;

Texture g_Texture;
sampler g_Sampler = sampler_state
{
	Texture = g_Texture;
	AddressU = Clamp;
	AddressV = Clamp;
};

struct VertexShaderInput
{
    float4 vPosition : POSITION0;
	float2 vTextureCoordinate : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 vPosition : POSITION0;
	float2 vTextureCoordinate : TEXCOORD0;
};

VertexShaderOutput DefaultVertexShader(VertexShaderInput _Input)
{
	VertexShaderOutput Output;

	Output.vPosition = mul(_Input.vPosition, g_mWorldViewProjection);
	Output.vTextureCoordinate = _Input.vTextureCoordinate;

	return Output;
}

float4 DefaultPixelShader(VertexShaderOutput _Input) : COLOR0
{
	float4 vColor = tex2D(g_Sampler, _Input.vTextureCoordinate);

	return vColor;
}

float4 TacticalPixelShader(VertexShaderOutput _Input) : COLOR0
{
	float4 vColor = float4(0, 0, 0, 0);
	float4 vNeighbors[4] = 
	{
		tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x - g_fBlurSize, _Input.vTextureCoordinate.y)),
		tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x + g_fBlurSize, _Input.vTextureCoordinate.y)),
		tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y - g_fBlurSize)),
		tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y + g_fBlurSize))
	};

	float fDepth = tex2D(g_Sampler, _Input.vTextureCoordinate).a;

	for(int i = 0; i < 4; ++i)
	{
		float fNeighborDepth = vNeighbors[i].a;

		// Find the distance from the neighboring pixel to the current pixel
		float fDepthDifference = fDepth - fNeighborDepth;

		// If the current pixel is in behind the neighboring pixel
		if(fDepthDifference > 0.005)
		{
			// Draw an outline
			vColor = g_vOverlayColor;
			break;
		}
	}

    return vColor;
}

float4 BlurHorizontalPixelShader(VertexShaderOutput _Input) : COLOR0
{
	float4 vColor = float4(0, 0, 0, 0);

	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x - 4.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.05;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x - 3.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.09;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x - 2.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.12;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x - g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.15;

	vColor += tex2D(g_Sampler, _Input.vTextureCoordinate) * 0.16;

	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x + g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.15;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x + 2.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.12;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x + 3.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.09;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x + 4.0f * g_fBlurSize, _Input.vTextureCoordinate.y)) * 0.05;

    return vColor;
}

float4 BlurVerticalPixelShader(VertexShaderOutput _Input) : COLOR0
{
	float4 vColor = float4(0, 0, 0, 0);

	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y - 4.0f * g_fBlurSize)) * 0.05;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y - 3.0f * g_fBlurSize)) * 0.09;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y - 2.0f * g_fBlurSize)) * 0.12;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y - g_fBlurSize)) * 0.15;

	vColor += tex2D(g_Sampler, _Input.vTextureCoordinate) * 0.16;

	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y + g_fBlurSize)) * 0.15;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y + 2.0f * g_fBlurSize)) * 0.12;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y + 3.0f * g_fBlurSize)) * 0.09;
	vColor += tex2D(g_Sampler, float2(_Input.vTextureCoordinate.x, _Input.vTextureCoordinate.y + 4.0f * g_fBlurSize)) * 0.05;

    return vColor;
}


technique Default
{
    pass Pass1
    {
		VertexShader = compile vs_3_0 DefaultVertexShader();
        PixelShader = compile ps_3_0 DefaultPixelShader();
    }
}

technique Tactical
{
    pass Pass1
    {
		VertexShader = compile vs_3_0 DefaultVertexShader();
        PixelShader = compile ps_3_0 TacticalPixelShader();
    }
}

technique Horizontal_Blur
{
    pass Pass1
    {
		VertexShader = compile vs_3_0 DefaultVertexShader();
        PixelShader = compile ps_3_0 BlurHorizontalPixelShader();
    }
}

technique Vertical_Blur
{
    pass Pass1
    {
		VertexShader = compile vs_3_0 DefaultVertexShader();
        PixelShader = compile ps_3_0 BlurVerticalPixelShader();
    }
}